#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <net/if.h>  // 用于网卡绑定

#define MULTICAST_GROUP "224.1.1.1"
#define PORT            12345
#define INTERFACE      "ens34"  // 指定网卡名称

int main(int argc, char* argv[])
{
    char ifc[32] = { 0 };
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <interface>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    strncpy(ifc, argv[1], sizeof(ifc) - 1);

    int sockfd;
    struct sockaddr_in multicast_addr;
    char message[64] = { 0 };
    struct ip_mreqn mreq;  // 用于设置组播网卡

    // 1. 创建UDP套接字
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 2. 初始化组播地址结构
    memset(&multicast_addr, 0, sizeof(multicast_addr));
    multicast_addr.sin_family = AF_INET;
    multicast_addr.sin_addr.s_addr = inet_addr(MULTICAST_GROUP);
    multicast_addr.sin_port = htons(PORT);

    // 3. 设置组播数据的出口网卡（关键步骤）
    memset(&mreq, 0, sizeof(mreq));
    mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);
    mreq.imr_address.s_addr = INADDR_ANY;  // 系统自动选择IP
    // mreq.imr_address.s_addr = inet_addr("192.168.31.105");  // 选择IP
    mreq.imr_ifindex = if_nametoindex(ifc);  // 绑定到 网卡ifc 的接口索引

    if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)) < 0) {
        perror("setsockopt(IP_MULTICAST_IF) failed");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // 4. 发送组播数据
    int count = 60;
    while (count-- > 0) {
        snprintf(message, sizeof(message) - 1, "hello this multicast test: %d", count);
        if (sendto(sockfd, message, strlen(message), 0,
            (struct sockaddr*)&multicast_addr, sizeof(multicast_addr)) < 0) {
            perror("sendto failed");
            close(sockfd);
            exit(EXIT_FAILURE);
        }
        sleep(1);
    }

    printf("Multicast message sent via %s: %s\n", ifc, message);
    close(sockfd);
    return 0;
}

/* 测试1: 指定网卡 ens33
3_udp组播multicast_发送sender_指定网卡.out ens33

tcpdump结果
sudo tcpdump  -i ens33 "dst host 224.1.1.1 and dst port 12345"
06:25:27.178740 IP 192.168.5.13.35634 > 224.1.1.1.12345: UDP, length 29
06:25:28.179006 IP 192.168.5.13.35634 > 224.1.1.1.12345: UDP, length 29
06:25:29.179265 IP 192.168.5.13.35634 > 224.1.1.1.12345: UDP, length 29
06:25:30.179519 IP 192.168.5.13.35634 > 224.1.1.1.12345: UDP, length 29
 */


/* 测试2: 指定网卡 ens34
3_udp组播multicast_发送sender_指定网卡.out ens34

tcpdump结果
sudo tcpdump  -i ens34 "dst host 224.1.1.1 and dst port 12345"
06:26:12.844807 IP zero.33352 > 224.1.1.1.12345: UDP, length 29
06:26:13.845763 IP zero.33352 > 224.1.1.1.12345: UDP, length 29
06:26:14.846189 IP zero.33352 > 224.1.1.1.12345: UDP, length 29
 */